﻿using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Options;
using RuoVea.ExFilter;
using RuoVea.OmiApi.Dict;
using RuoVea.OmiApi.Reports;
using RuoVea.OmiReports.Attributes;
using RuoVea.OmiReports.Language;
using RuoVea.OmiReports.Options;
using RuoVea.OmiUI;
using SqlSugar;
using System.Text.Encodings.Web;
using System.Text.Unicode;
using omiApp = RuoVea.OmiApi.Reports;
using omiDict = RuoVea.OmiApi.Dict;

namespace RuoVea.OmiReports;

/// <summary>
/// 注入扩展
/// </summary>
public static class ServiceCollectionExtensions
{
    /// <summary>
    /// 报表管理接口
    /// </summary>
    /// <param name="services"></param>
    /// <param name="serviceLifetime"></param>
    /// <returns></returns>
    /// <exception cref="ArgumentNullException"></exception>
    public static IServiceCollection AddOmiReportSetup(this IServiceCollection services, ServiceLifetime serviceLifetime = ServiceLifetime.Scoped)
    {
        if (services == null) throw new ArgumentNullException(nameof(services));
        return DI(services, null, serviceLifetime);
    }

    /// <summary>
    /// 报表管理接口
    /// </summary>
    /// <param name="services"></param>
    /// <param name="config"></param>
    /// <param name="serviceLifetime"></param>
    /// <returns></returns>
    /// <exception cref="ArgumentNullException"></exception>
    public static IServiceCollection AddOmiReportSetup(this IServiceCollection services, IConfiguration config, ServiceLifetime serviceLifetime = ServiceLifetime.Scoped)
    {
        if (services == null) throw new ArgumentNullException(nameof(services));
        if (config == null) throw new ArgumentNullException(nameof(config));
        services.Configure<AppConfig>(config);
        AppConfig appConfig = services.BuildServiceProvider().GetRequiredService<IOptions<AppConfig>>()?.Value;
        return DI(services, appConfig, serviceLifetime);
    }

    /// <summary>
    /// 报表管理接口
    /// </summary>
    /// <param name="services"></param>
    /// <param name="config"></param>
    /// <param name="serviceLifetime"></param>
    /// <returns></returns>
    /// <exception cref="ArgumentNullException"></exception>
    public static IServiceCollection AddOmiReportSetup(this IServiceCollection services, Action<AppConfig> config, ServiceLifetime serviceLifetime = ServiceLifetime.Scoped)
    {
        if (services == null) throw new ArgumentNullException(nameof(services));
        if (config == null) throw new ArgumentNullException(nameof(config));
        services.Configure(config);
        AppConfig appConfig = services.BuildServiceProvider().GetRequiredService<IOptions<AppConfig>>()?.Value;
        return DI(services, appConfig, serviceLifetime);
    }

    #region DI
    private static IServiceCollection DI(IServiceCollection services, AppConfig appConfig, ServiceLifetime serviceLifetime)
    {
        if (appConfig == null && !string.IsNullOrWhiteSpace(appConfig?.PrefixRoute))
            if (!appConfig.PrefixRoute.StartsWith('/'))
                throw new ArgumentNullException(i18n.prefixroute);

        ConfigManages.Config = appConfig;
        services.AddControllers().AddJsonOptions(o => { o.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All); /*返回中文字符不转译*/ });

        services.AddRestfulModelsSetup();

        services.AddOmiDictSetup(serviceLifetime);
        //services.AddOmiReportSetup(serviceLifetime);
        //omiDict.ServiceCollectionExtensions.AddOmiDictSetup(services, serviceLifetime);
        omiApp.ServiceCollectionExtensions.AddOmiReportSetup(services, serviceLifetime);

        services.AddControllersWithViews().AddRazorRuntimeCompilation(option =>
        {
            option.FileProviders.Add(new EmbeddedFileProvider(typeof(Controllers.RptDatabaseController).GetTypeInfo().Assembly));
            option.FileProviders.Add(new EmbeddedFileProvider(typeof(Controllers.RptQueryController).GetTypeInfo().Assembly));
            option.FileProviders.Add(new EmbeddedFileProvider(typeof(Controllers.RptSqlController).GetTypeInfo().Assembly));
        });
        return services;
    }
    #endregion

    /// <summary>
    /// 初始化数据库/初始化种子数据
    /// </summary>
    /// <param name="services"></param>
    /// <returns></returns>
    /// <exception cref="ArgumentNullException"></exception>
    public static IServiceCollection AddReportInitSetup(this IServiceCollection services)
    {
        if (services == null) throw new ArgumentNullException(nameof(services));
        services.AddDictInitSetup();
        omiApp.ServiceCollectionExtensions.AddReportInitSetup(services);
        return services;
    }

    /// <summary>
    /// 报表管理页面UI
    /// </summary>
    /// <param name="app"></param>
    /// <returns></returns>
    public static IApplicationBuilder UseOmiReportUI(this IApplicationBuilder app)
    {
        app.UseOmiUIStaticAssets();
        app.UseStaticFiles(new StaticFileOptions { FileProvider = new EmbeddedFileProvider(typeof(Controllers.RptDatabaseController).GetTypeInfo().Assembly) });
        app.UseStaticFiles(new StaticFileOptions { FileProvider = new EmbeddedFileProvider(typeof(Controllers.RptQueryController).GetTypeInfo().Assembly) });
        app.UseStaticFiles(new StaticFileOptions { FileProvider = new EmbeddedFileProvider(typeof(Controllers.RptSqlController).GetTypeInfo().Assembly) });

        return app;
    }

}
